perm filename 11FTP.SAI[11,HE]4 blob sn#590383 filedate 1981-06-01 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00007 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	BEGIN "FTP Program"
C00004 00003	! Auxiliary routines: parse10, parse11, outbuf, inbuf
C00008 00004	! Main program - initialization
C00012 00005	! Command loop - Exit & Alias
C00014 00006	! Store 11file ← 10file
C00019 00007	! Get 10file ← 11file & Fin
C00023 ENDMK
C⊗;
BEGIN "FTP Program"

DEFINE	CRLF="('15&'12)",
	CR  ="'15",
	LF  ="'12",
	FF  ="'14",
	! = "COMMENT ",
	TIL="STEP 1 UNTIL";

REQUIRE "11UTIL.HDR[11,SYS]" SOURCE_FILE;

DEFINE TTYSET = "'047000400121";
DEFINE GETLIN = "'051311qqA∪X4*∩,2&:∃∧:⊗RB∧q↓u↓∩9AQ]β↓AAAβ↓IQ	Xh(4*LrR⊗≡-⊃βCCsX%¬α>C=∨Mπ∪W;;Ns≥β≠'↓⎇l4TJ:R⊗<*Iβ∂F9l%
↓α∂#∞s;↔1εsW7/⊃β≠?∩α%>=π#=αJ≥Al4*LrR⊗≡-⊃β∪O↑≠#π9Z↓↓¬↓∧≠#π;v+1β;.k↔Iε3?I↓↓β∪'≡Yα%>{X4*⊗E"⊗J:aα&:$*≡⊗I↓BN.&↓Al4(hR&:R,:⊗Iα
∩Jεeε∪W≠≠/∩mEi∪)ZulhR&:R,:⊗Iβ&3-Eαc∂#π∩cA3%fQ3-3bc∪W5f≠?77∞s⊃3⊗Y3K[	3↔?2cπO*cW≠∞#I3.3CSIg;πK9Xh*NR∀J:≥β3	3→Ig→3E3≡{53π≡Y3≠∪/1EE36sπ5Eαc≠;πk	E3≠/CQEAf3↔cQ	3≠[/⊃EE3πβ9EAgβC9EX4*N%∩&:≥ε3CCs	E3πf#↔YEX4*2∩⊗1β6K9l4Ph(1¬α∂+c'3NKeβ⊗{WS'v+MiβεKO∃↓1βC∂∪O∃E
aβ?W&∪W→1εK;W3X4(4UαJ>∞,"VJ∃πβπKO+	A↓"≥"J&::βM%lhQ↓α
,:&84R↓β≠;∞iEAαzβ≠↔c#	Aα⎇πβC9Eαα⎇α:,b1l4R	α↑"Lb∃βMj⊃↓	"βMm∧rV21∧"=β∪.iα⎇αdzA#MKX%¬α∨#K'Aε{≠→βf+π∪'v9β3∞s/MlhQ↓α↑DJ2∃β→Y	9	!βLm∃Y	⊃π_n:Vdaα∩=ε3;π5↓α⎇β6sπ5Eα↓→α2⎇↓#M%Z↓↓¬α↔+'3⊃π+Aβ≠Nc∃β;∞k∃l4R↓α↑"Lb∃βLZ∩m	"βLn:,b1α∩zβ≠↔c#	Aα⎇ε3↔cQ↓↓→αdzA#MKX%¬α↔+'3⊃π+Aβ≠Nc∃β↔G#↔;ON{9l4R↓α&→π→u
m∩αR"⊗rβCC9↓α⎇β≠X$%¬¬≠↔Qβπβ9β'2βCK↔≡+;QlhQ↓α⊗t!l4(hRBJ>≤*∩VJ*βCπK≡)EE↓E~RJ&t9βM%Xh)↓α∀*≡&8hQ↓β≠&+YEE¬yβπ3&+YEEXh)↓βπβ9EE¬yβπ3πβ9EEXh)↓β6sπ5E
α⎇β≠/CQEE¬yα:Vdal4)αβ≠[↔∪	Eα⎇α⊃mA	XI¬α∪.3πW3"β[↔K≡K?9βw+7↔∩↓5β7.;Mβn{OQβ⊗+∂↔;"β[↔K≡K?9lhQ¬α↑DJ2∃β≠i	↓	!βMZα:V2bα∩=β'+5α⎇∧b>A#~Il%¬¬≠SK'αβ?≠→εc↔π∪Ns≥βf;/MXh)↓αL1βLm∃Y	⊃αCNmI∧2>I↓
iu	i∩⎇βN[→α~>∩↓Fuu∪Q	⎇π~mQα4zI↓Fki	i	JαR"⊗ph)↓↓αα
⊗≡Lp$$$J	αO↔"β∪↔[N≠∃β;∞k∃l4R↓↓↓β6#↔YE
α⎇α2⎇↓#M%Xh)↓↓αα↑"&d)βLm∪Q	α∩zβ≠∪↔3	Eα⎇ε3∪↔Y	↓→αdzA#MKX4)↓α↓β≠∪/1EEαzβ≠∪↔3	E↓→∧b>A#~Il4)α↓↓α⊗t!l4)αα&→β≠i
m	¬""⊗8HH$%¬¬≠↔Qβπβ9β'2βCK↔≡+;QlhQ↓↓↓∧∩⊗≡&ph)↓↓αβCC9	α⎇αu*21lhQ↓↓↓∧"=βCεqEEαzβCC9	↓→αdzA#MJαV:RLaβMu∃i	⎇π→v:Vdal%¬∧∪W'3"βWAβπβ9l4R↓↓↓βπβ9EE¬yβCCs	E↓→∧b>A#~Il$$HI¬αS∞≠-β?rβ≠';∞a↓
u∪X4)↓α↓α⊗:#X4)↓¬:"&2*βLm	r⊃⊃β→Y	m	!βLnu*21α$yβ≠;∞iEEαzβ≠;πk	E↓→∧b>A#~Im↓↓
αW'f!βWAε3'3∃εsπ7∃Xh)↓α<B&2∃π_m	m∩⊃βL\rV21∧"=β≠/CQEE¬yβ≠↔G!EE↓2α2>AG→%l%
αW'f!βWAε3'3∃ε+cS↔w≠'?9Xh)↓αL1βMu∪Y	αRD*9β≠6+IEE¬yβMlHI¬αO/!β[↔↔≠'?9εsW7/⊃β'→πβK↔O.sQl4R↓α⊗:#X4(4UαJ>∞,"VJ∃∧zVR
,1l4)αα
⊗≡Lp4)↓¬:"&2*↓#W6∪J}∧*⊗-#↔+≠CS∩I%uA∧"=α∞b1!Ab∩N2⊗-↓	%mα↓↓¬α≡c↔↔Aε3?I↓
βS'∂[X4)↓∧J→β.3π∪I∧bε:⊃β	αR",q↓↓↓
αO?7/##';:;Mβ←⊗{;≥↓jβπ?↔!l4)α↓↓α
,:&84R↓↓↓αL1βSπfYEAα$B⊗9α¬∩&:QB∩↔KK␈⊃β←#Nc∃β←⊗KS';:β≠'3*⊃≠∂Kf1%l4R↓↓↓α<yαR=ε3'9lhQ↓↓↓∧*:⊃lhQ↓β.3π∪I¬yβW6∪I↓ZβπO+X4)↓∧J→β)¬""⊗9¬α>.∃F∪W≠C'⊃-I3RIl$%
αS↔3b↓EEβ&C'MβO→β3π∨!β3}≠-l4R↓αB>\*εJJ
I#W6∪I1∪)Y3.3≠↔Ic↓%l%
αSKπw≠≠↔Iπ##∃β≡+∂S?∩β?[↔∪X4)¬¬α>.⊗
∩JεeF∪W≠π'⊃1IU2cW≠6+I2R=∩)%lJ	αSK∞sO≠↔∩βS#∃π≠↔∂S␈⊃β?[/⊃l4)ααB>.*CW≠π#I1AKX$$%
αS↔3b↓EEβ&yβ↔7π#eβ.3≠↔Iεs?]lhQ↓β%¬y↓ElhQ↓α⊗t!l4(hRBJ>≤*∩VJ*α&:
,1l4)αα
⊗≡Lp4)↓¬:"&2*↓#W6∪J}∧*⊗-#↔+≠CS∩I%uA∧"=α∞b1!Ab∩N2⊗-↓	%mα↓↓¬α≡c↔↔Aε3?I↓
βS'∂[X4)↓∧J→β.3π∪I∧bε:⊃β	αR",p%¬α≡{7↔SFK;≥∨~β←K?v9↓5β∞∪?KQXh)↓↓α↓α
⊗<J84)α↓↓↓αL1βSπfYEAα$B⊗9α¬∩&:QB∩↔KK␈⊃β←#Nc∃βK.∪';:β≠'3*⊃≠∂Kf1%l4R↓↓↓↓∧:=αRzβ≠'9Xh)↓↓α↓α⊗:#X4)↓ε∪W≠π'⊃α⎇β↔+≠π∪∩↓-β∂≠∃l4R↓αB⊗,ZεJJ
I#W6∪I1∪)Y3.3≠↔Ic↓%l%
αSKπw≠≠↔Iπ##∃β≡+∂S?∩β?[↔∩βS=↓↓l4)αβ)α⎇¬α⊗⊗-F∪W≠C'⊃-I%∧"&Y↓∪X$%¬∧;↔Qβ6KKOQε3K↔∃π;?K⊃εK→β3∂≠Qβf{∂-lhQ↓αB|Z∃#.3CSIc↓%l$HI¬αS.c1↓E
β←∃∨⊗)β∪?v)β←'&AβW63↔IlhQ↓β%¬y↓ElhQ↓α⊗t!l4(hP1¬αn'9βπ∪?∨K∞i↓5βNs'S'∞c'kπ&K?9lhP4*N-"
J⊗Y!E3∨∪3→2u*211∀J:M	KX4*N-"
J⊗Y!I3f1≠≠→f≠I1
LrM	%Xh*N⊗$∩J⊗εZAM1λWp∧λ (_ ,px@DH→ TX\AHlptqy	2:,b11
LrM	%XI¬α∂}s[↔K≡K?;Mε3?I↓	l4*≤*R
J,
-!Qb⊂i	→;	M]→;	]U2u*211∀J:M	KX$$%
α∂?;6+KO'}sMβ≠⊗{5↓EX4*N-"
J⊗Y!U1∪j⎇	1∩↓	1
\J:M	KX$$$J	α∂?w3↔KQπ#=βWπβ↔K∂∂≠∃l4Ph+π3&+YEE¬y↓
εcQ	l%
αOSπv#πK⊃ε3'π≡K;≥lhRFV&≤Xb∞>$(4)α<*RBBr↓≥EMcX$%¬¬;#=∨~βKW;vK;≥β/→⎇l4Rα"J2Ti↓≥E~bBB9Xh)α⊗t!l4+∞cCC9	α⎇αL1βCCr↓uα∞5~&a!∀
J≥	JαR"⊗r↓
mEc	BuλhP&⊗2≤)α&→¬αB9↓jα∞ZNMA!	α∃1	%α$B⊗9↓∃Y]1E5iλ4(L*2N∃∧J→αB∧q↓uα≥2N&aB∩**
∩IαR",q↓
m*aVuλhP&⊗2≤)↓
m∪↓A1Iβαu	lhP4*εdJ:&QF3π3O*Il%¬∧OO'>qβS#*α⊗2→bβWQε#?9∨"β∂πK*βπ?/!αεJkX4(4R	αO↔*β←#↔&C↔I↓↓β?Iβ	Eβ'~βK↔G.+OS'v9βS#*βSKπw≠≠↔IXh(4+&3-Eαα⎇↓5X4*∞|"∃"≡-"2&9g#π3-↓%l%
βSπ3[	Aβ;␈9β#π~βS↔KnK;π1ε≠#πK∞≠S↔KO≠S'∂~↓→β3Ns∃β;.k↔IXh+SπfYEAαzα&→↓G#π3-↓α2εt!↓≥];9]%u;)MαRD*9α~bN∃α,bN∃α%∩V∃lhP4*&2βSπ3[	AαRD*84)αα
⊗≡Lp4)↓¬αJ&:"C∂K32↓→↓	↓5EE∧2RAαπ∪?∨K∞i9↓α'KC∃↓zβ≠?IεC↔3Ar⊃3∂Kf1%l4R↓αBJLrQ↓!∀#↔≠π.cQ↓E
αBB9ε3?IβN{Uβ'~αε1i∩cπ3CεqEE3∨∪3→3∨∪3→%Xh)↓β≡Cπ9αzα≡⊗R≤Bε9lhQ↓α>∧*9#∂F91
%"eUM∩aA1Ec	1eeJcK-
c∪W5KX4)↓α↓αFVL~,b∞|"∀4(Lbε
⊗bαb&Qe~⊗RVβX4(&E∩J%↓;	M2N-"VAlHI↓↓↓α	α∂?nkπ;⊃εc'OQπ#=β'vKS'πfKk∃β&C∃βS'Il4(LBJ2%α9EM1k→l$%α↓↓↓¬∧sW7/⊃β?→ε≠?77∞s∪MlhP&RRM~⊗Q↓;	M1AXH%↓↓α↓¬α∪zβ'QlhP&*J≥ &b*N-"VAhhQ∧%≥β9IQU≠↓AAAβ	l$%
αO↔Q¬"Reα-B&NQXh)∧%;↓QAQ+→AAAβ↓Ul$J	αO↔"βSSeπ≠C↔↔"↓u↓E∪↓Aβ∂+⊃l4PI≥AA!UMAβ↓AAQXH%¬α≡+Q↓"Dz9↓→Jα:=α,~"=lhP%≥Aβ⊃QUMβ	AAAβX$%¬¬≠↔Qα%"eα:zαεJJ⎇9⎇l4PI≥AI≠!UMAβ↓AAEXH%¬α≡+QαR%Iα≡ε;X4*bM!h&⊗t!l4(hQ↓α>-!#∂#∞q1
J,q↓⊃E2RA	6≠K3→KX4)↓¬:"&2*α&:B-!#∂#∞q1E%βiα:Vdaα∩=βY↓¬αN;;?K*β↔∂#zβ≠K?jαJNaXh)↓α<B&2∃αCN}&uαVQ#≡Cπ91
I%↓u∧rV21↓yβMu∪q	α∩z↓l4)αβπO*α⎇α∞4y#M%∧bN!↓3X$$%
α∨↔Qε∪∪K/≠Mβ?2αCπK&KS'?rαπO+X4)¬¬αJ&:"A
Cπ↔#'S'}qβπ≡)↓u↓∩b∞Z>~CπO*I3∂Kf1%l4R↓α↑"Lb∃↓#≥z&:B-!#∂#∞q1E%J↓uα:,b1α∩z↓l4)αβW≠π#Iα⎇∧~Z=#~Il$$J	α∨↔"βπ∪∪⊗+OMβ}1βW63↔Iβε{';S/⊃l4)
αBJ&u!!
.3≠↔Iπβ?';&+I↓uα⊃2∞Z⎇→#W7βSI%f≠K3→KZ⎇'T
  END
 ELSE
  BEGIN
  base ← CVO(INCHWL) LSH 6;		! Get address of buffer pointer;
  bufptr ← CVO(INCHWL);			! Get address of buffer pointer;
  END;
bufptr ← base + bufptr;

dskchan ← GETCHAN;
OPEN(dskchan,"DSK",0,19,19,512,brk,eof);

! Command loop - Exit & Alias;

WHILE TRUE DO		! Get a command & do what needs doing;
  BEGIN
  PRINT("*");
  warn ← 0;
  com ← INCHWL;		! Read command;
  command ← LOP(com) LOR '40;	! command = x, q, e, d, g or s for now;
  IF command = "x" ∨ command = "e" ∨ command = "q" ∨ command = "d" THEN
    BEGIN
    IF talk10 THEN OUT(chan,"E"&cr&cr);	! Tell 11 that we're done;
!   IF talk10 THEN OUT(chan,"X"&cr&cr);	! Tell 11 that we're done;
    WHILE (s←INPUT(chan,1)) = NULL ∨ s≠">" DO ;	! Wait for MCR prompt;
    i ← WORDIN(chan);		! This should clear the buffer;
    IF command = "d" THEN
      BEGIN			! Now invoke DIAL;
      CLRBUF;
      PTOSTR(0,"DIAL TTY53"&crlf);
      END;
    CALL(0,"EXIT");
    END;

  f1 ← SCAN(com,5,i);	! Get first file name & convert it to upper case;
  f2 ← SCAN(com,5,i);	! Get second file name & convert it to upper case;
  IF command = "a" THEN
    BEGIN		! Get device & UIC alias for 11;
    parse11(f1);	! Info now in fdev11 & ppn11;
    aldev11 ← fdev11;
    alppn11 ← ppn11;
    END
! Store 11file ← 10file;

  ELSE IF command = "s" THEN
    BEGIN		! Store 11file ← 10file;
    IF talk10 THEN
      BEGIN
      PARSE11(f1);
      PARSE10(f2);
      IF fnam11 = NULL THEN fnam11 ← fnam10;
      IF fext11 = NULL THEN fext11 ← fext10;
      IF fnam10 = NULL THEN fnam10 ← fnam11;
      IF fext10 = NULL THEN fext10 ← fext11;
      END
     ELSE PARSE10(f1);
    LOOKUP(dskchan,fnam10 & fext10 & ppn10,i);
    IF i THEN
      BEGIN PRINT("ABORTED - Can't find:",fnam10,fext10,ppn10,crlf); GO TO fin END;
    IF talk10 THEN
	BEGIN		! Tell 11 name of file to create;
	OUT(chan,"G " & fdev11 & ppn11 & fnam11 & fext11 & fver11 & cr);
	WHILE INPUT(chan,1) = NULL DO ; ! Ignore echo;
	WHILE (s←INPUT(chan,1)) = NULL DO ;
	IF ¬EQU("OK",s) THEN
	  BEGIN PRINT("Aborted by 11 "&s&crlf); GO TO fin END;
	END
     ELSE PRINT("OK"&crlf);
    eof ← FALSE;
    i ← j ← 0;
    s ← INPUT(dskchan,2);		! Read in the first line;
    IF EQU(s[1 FOR 9],"COMMENT ⊗") THEN
	BEGIN   ! Skip over E directory page;
	DO s ← INPUT(dskchan,2)		! Read in the next line;
	    UNTIL EQU(s[1 FOR 3],"C⊗;") ∨ eof;
	IF eof THEN
	    BEGIN
	    IF talk10 THEN PRINT("Directory end not detected"&crlf);
	    s ← NULL;
	    END;
	s ← INPUT(dskchan,2);	! Skip ff;
	s ← INPUT(dskchan,2);	! Read in the first real line;
	END;
    DO BEGIN			! Start transferring characters to the 11;
	q ← NULL;
	WHILE s≠NULL DO
	    BEGIN		! Convert Stanford ASCII to standard ASCII;
	    q ← q & SCAN(s,3,char);	! Scan to next conversion;
	    IF char = 0 THEN		! nothing to do;
	    ELSE IF char = "~" THEN q ← q & '176
	    ELSE IF char = "}" THEN q ← q & '175
	    ELSE IF char = "_" THEN q ← q & '137
	    ELSE IF char = "≥" THEN q ← q & ">="	! Be nice here;
	    ELSE IF char = "≤" THEN q ← q & "<="
	    ELSE IF char = "≠" THEN q ← q & "<>"
	    ELSE IF char = "¬" THEN q ← q & " not "
	    ELSE IF char = "∧" THEN q ← q & " and "
	    ELSE IF char = "∨" THEN q ← q & " or "
	    ELSE warn ← warn + 1;	! Count characters we omitted;
	    END;
	s ← q;
	IF brk = ff THEN s ← s & ff;
	IF (i←i+1) > 256 THEN OUTBUF;
	buffer[i] ← LENGTH(s);	! How long is this record?;
	WHILE s ≠ NULL DO	! Stick them in the buffer 2/wd;
	  BEGIN
	  IF (i←i+1) > 256 THEN OUTBUF;
	  buffer[i] ← LOP(s) + (LOP(s) LSH 8);
!	  buffer[i] ← (LOP(s) LSH 18) + (LOP(s) LSH 26) + LOP(s) + (LOP(s) LSH 8);
	  END;
	s ← INPUT(dskchan,2);	! Read in the next line;
       END UNTIL eof ∧ LENGTH(s)=0;
    j ← 2*i;				! First free byte address;
    FOR k ← i+1 TIL 256 DO buffer[k]←0;	! Clear out end of block;
    OUTBUF;				! And send it over to the 11;
    END
! Get 10file ← 11file & Fin;

   ELSE IF command = "g" THEN
    BEGIN		! Get 10file ← 11file;
    PARSE10(f1);
    PARSE11(f2);
    IF fnam10 = NULL THEN fnam10 ← fnam11;
    IF fext10 = NULL THEN fext10 ← fext11;
    IF fnam11 = NULL THEN fnam11 ← fnam10;
    IF fext11 = NULL THEN fext11 ← fext10;
    ENTER(dskchan,fnam10 & fext10 & ppn10,i);
    IF i THEN
      BEGIN PRINT("ABORTED - Can't enter:",fnam10,fext10,ppn10,crlf); GO TO fin END;
    IF talk10 THEN
	BEGIN		! Tell 11 name of file to read;
	OUT(chan,"S " & fdev11 & ppn11 & fnam11 & fext11 & fver11 & cr);
	WHILE INPUT(chan,1) = NULL DO ; ! Ignore echo;
	WHILE (s←INPUT(chan,1)) = NULL DO ;
	IF ¬EQU("OK",s) THEN
	  BEGIN PRINT("Aborted by 11 "&s&crlf); GO TO fin END;
	END
     ELSE PRINT("OK"&crlf);
    i ← 256;
    j ← 0;
    WHILE j=0 ∨ i<j DO		! Start transferring characters to the 10;
	BEGIN
        IF (i←i+1) > 256 THEN INBUF;
        k ← buffer[i];		! Get byte count;
	s ← NULL;
	FOR l ← 1 STEP 2 UNTIL k DO	! unpack them from the buffer 2/wd;
	  BEGIN
	  IF (i←i+1) > 256 THEN INBUF;
	  p ← POINT(8,buffer[i],27);	! 11 for 4/wd;
	  char ← LDB(p);
	  s ← s & ILDB(p) & char;
!	  q ← ILDB(p) & char;
!	  char ← ILDB(p);
!	  s ← s & q & ILDB(p) & char;
	  END;
	IF k MOD 2 THEN s ← s[1 FOR k];
	q ← NULL;
	WHILE s≠NULL DO
	    BEGIN		! Convert standard ASCII to Stanford ASCII;
	    q ← q & SCAN(s,4,char);	! Scan to next conversion;
	    IF char = 0 THEN		! nothing to do;
	    ELSE IF char = '176 THEN q ← q & "~"
	    ELSE IF char = '175 THEN q ← q & "}"
	    ELSE IF char = '137 THEN q ← q & "_"
	    ELSE warn ← warn + 1;	! Count characters we omitted;
	    END;
	s ← q;
	IF EQU(s,ff) THEN OUT(dskchan,s)
		     ELSE OUT(dskchan,s & crlf);  ! Write out the next line;
	END;
    END
   ELSE BEGIN "Help them out"
     PRINT("G to get a file from the 11"&crlf);
     PRINT("S to store a file on the 11"&crlf);
     PRINT("A to set an alias device & UIC on the 11 {default= AL:",alppn11,"}"&crlf);
     PRINT("X to exit" &crlf);
     PRINT("D for DIAL" &crlf&crlf);
     END;
fin:
  CLOSE(dskchan);
  IF warn THEN 
    PRINT("*WARNING* - file contained: ",warn," nonstandard characters."&crlf);
  END;

END;